package cn.sccdlg.lambda.demo03.stream;

import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import java.util.stream.Stream;

/**
 * @author RaoShuang
 * @emil 991207823@qq.com
 * @date 2020/6/7 21:34
 * 集合元素的常见操作
 */
public class StreamTest03 {
    public static void main(String[] args) {
        // 1. 批量数据 -> Stream对象
        // 多个数据
        Stream stream = Stream.of("admin", "tom", "damu");

        // 数组
        String [] strArrays = new String[] {"xueqi", "biyao"};
        Stream stream2 = Arrays.stream(strArrays);

        // 列表
        List<String> list = new ArrayList<>();
        list.add("少林");
        list.add("武当");
        list.add("青城");
        list.add("崆峒");
        list.add("峨眉");
        Stream stream3 = list.stream();

        // 集合
        Set<String> set = new HashSet<>();
        set.add("少林罗汉拳");
        set.add("武当长拳");
        set.add("青城剑法");
        Stream stream4 = set.stream();

        // Map
        Map<String, Integer> map = new HashMap<>();
        map.put("tom", 1000);
        map.put("jerry", 1200);
        map.put("shuke", 1000);
        Stream stream5 = map.entrySet().stream();

        // 2. Stream对象对于基本数据类型的功能封装
        // int / long / double
        IntStream.of(new int[] {10, 20, 30}).forEach(System.out::println);
        //不含结束数据
        IntStream.range(1, 5).forEach(System.out::println);
        //包含结束数据
        IntStream.rangeClosed(1, 5).forEach(System.out::println);

        // 3. Stream对象 --> 转换得到指定的数据类型(只能进行单次操作不然报错：stream has already been operated upon or closed)
        // 数组
        /*Object [] objx = stream.toArray(String[]::new);*/
        //字符串
        /*String str = stream.collect(Collectors.joining()).toString();
        System.out.println(str);*/
        //列表
        /*List<String> listx = (List<String>) stream.collect(Collectors.toList());
        System.out.println(listx);*/
        //Set集合
        /*Set<String> setx = (Set<String>) stream.collect(Collectors.toSet());
        System.out.println(setx);*/
        //Map
        Map<String, String> mapx = (Map<String, String>) stream.collect(Collectors.toMap(x->x, y->"value:"+y));
        System.out.println(mapx);

        // 4. Stream中常见的API操作
        List<String> accountList = new ArrayList<>();
        accountList.add("songjiang");
        accountList.add("lujunyi");
        accountList.add("linchong");
        accountList.add("luzhishen");
        accountList.add("likui");
        accountList.add("wusong");

        // 4-1、map() 中间操作，map()方法接收一个Functional接口
        /*accountList = accountList.stream().map(x->"梁山好汉:" + x).collect(Collectors.toList());
        accountList.forEach(System.out::println);*/
        // 4-2、filter() 添加过滤条件，过滤符合条件的用户
        /*accountList = accountList.stream().filter(x-> x.length() > 5).collect(Collectors.toList());
        accountList.forEach(System.out::println);*/
        // 4-3、forEach 增强型循环(多次重复代码的输出推荐)
//        accountList.forEach(x-> System.out.println("forEach->" + x));
        // 4-4、peek() 中间操作，迭代数据完成数据的依次处理过程
        /*accountList.stream()
                .peek(x -> System.out.println("peek 1: " + x))
                .peek(x -> System.out.println("peek 2:" + x))
                .forEach(System.out::println);*/

        // 5、Stream中对于数字运算的支持
        List<Integer> intList = new ArrayList<>();
        intList.add(20);
        intList.add(19);
        intList.add(7);
        intList.add(8);
        intList.add(86);
        intList.add(11);
        intList.add(3);
        intList.add(20);

        // 5-1、skip() 中间操作，有状态，跳过部分数据
        //intList.stream().skip(3).forEach(System.out::println);
        // 5-2、limit() 中间操作，有状态，限制输出数据量
        //intList.stream().skip(3).limit(2).forEach(System.out::println);
        // 5-3、distinct() 中间操作，有状态，剔除重复的数据
        //intList.stream().distinct().forEach(System.out::println);
        // 5-4、sorted() 中间操作，有状态，排序
        intList.stream().sorted().forEach(System.out::println);

        // 6、max() 获取最大值
        Optional optional = intList.stream().max((x, y)-> x-y);
        System.out.println("最大值："+ optional.get());
        // 7、min() 获取最小值
        Optional optiona2 = intList.stream().min(Integer::compare);
        System.out.println("最小值："+ optiona2.get());

        // reduce() 合并处理数据
        Optional optional2 = intList.stream().reduce((sum, x)-> sum + x);
        System.out.println("所有数据的和是："+ optional2.get());
    }
}
